<?php
    /*
    * @Author: KingMin 
    * @Date: 2021-07-13 22:30:33 
    * @Last Modified by:   KingMin 
    * @Last Modified time: 2021-07-13 22:30:33 
    * @The authors website: https://www.kingmin.cn  
    */
/**
 * 生成文本缓存类
 *
 * @copyright (c) KINGMIN All Rights Reserved
 */

class Cache {

    private $db;
    private static $instance = null;

    private $options_cache;
    private $banners_cache;
    private $tabbars_cache;
    private $navi_cache;
    private $menus_cache;
    private $groups_cache;
    private $menuRole_cache;
    private $sensitives_cache;


    private function __construct() {
        $this->db = Database::getInstance();
    }

    /**
     * 静态方法，返回数据库连接实例
     *
     * @return Cache
     */
    public static function getInstance() {
        if (self::$instance == null) {
            self::$instance = new Cache();
        }
        return self::$instance;
    }
    /**
     * 更新缓存
     * 
     * @param array/string $cacheMethodName 需要更新的缓存，更新多个采用数组方式：array('options', 'user'),单个采用字符串方式：'options',全部则留空
     * @return unknown_type
     */
    function updateCache($cacheMethodName = null) {
        // 更新单个缓存
        if (is_string($cacheMethodName)) {
            if (method_exists($this, 'mc_' . $cacheMethodName)) {
                call_user_func(array($this, 'mc_' . $cacheMethodName));
            }
            return true;
        }
        // 更新多个缓存
        if (is_array($cacheMethodName)) {
            foreach ($cacheMethodName as $name) {
                if (method_exists($this, 'mc_' . $name)) {
                    call_user_func(array($this, 'mc_' . $name));
                }
            }
            return true;
        }
        // 更新全部缓存
        if ($cacheMethodName == null) {
            // 自动运行本类所有更新缓存的方法(此类方法的名称必须由mc_开头)
            $cacheMethodNames = get_class_methods($this);
            foreach ($cacheMethodNames as $method) {
                if (preg_match('/^mc_/', $method)) {
                    call_user_func(array($this, $method));
                }
            }
            return true;
        }
        return false;
    }
    /**
     * 站点配置缓存
     * 注意更新缓存的方法必须为mc开头
     */
    private function mc_options() {
        $options_cache = array();
        $res = $this->db->query("SELECT * FROM " . DB_PREFIX . "sys_config WHERE `isdel`='0' ");
        while ($row = $this->db->fetch_array($res)) {
            if($row['type']=='json'){
                $row['value']=json_decode($row['value'],true);
            }
            if($row['type']=='upload'){
                if($row['upload_type']=='2'){
                    $row['value']=json_decode($row['value'],true);
                } 
            }
            $options_cache[$row['fields']] = $row['value'];
        }
        $cacheData = serialize($options_cache);
        $this->cacheWrite($cacheData, 'options');
    }
    /**
     * 组合数据缓存
     * 注意更新缓存的方法必须为mc开头
     */
    private function mc_groups() {
        $groups_cache = Group_Model::getGroupCacheList();
        
        $cacheData = serialize($groups_cache);
        $this->cacheWrite($cacheData, 'groups');
    }
    /**
     * 菜单权限查询
     * 注意更新缓存的方法必须为mc开头
     */
    private function mc_menuRole() {
        $menuRole_cache = array();
        $query = $this->db->query("SELECT * FROM `".DB_PREFIX."sys_role` ");
        while ($row = $this->db->fetch_array($query)) {
            $rolemenu = array();
            $q = $this->db->query("SELECT * FROM `".DB_PREFIX."sys_role_menu` where `role_id`='".$row['role_id']."'");
            while ($v = $this->db->fetch_array($q)) {
                $que=$this->db->query("SELECT * FROM `".DB_PREFIX."sys_menu` where `menu_id`='".$v['menu_id']."' ");
                $m=false;
                while ($d = $this->db->fetch_array($que)) {
                    if($d['menu_type']=="F"){
                        $m=$d['menu_name']; 
                    }
                }
                if($m){
                    $rolemenu[]=$m;
                }
            }
            $menuRole_cache[$row['role_key']]=$rolemenu;
        }
        $cacheData = serialize($menuRole_cache);
        $this->cacheWrite($cacheData, 'menuRole');
    }
    /**
     * 后台菜单缓存
     */
    private function mc_menus() {
        $menu_cache = array();
        $menu=new Menu_Model();
        $menus = $menu->getAllrolemenu();
        foreach($menus as $k => $row){
            $menu_cache[$row['key']] = $row['list'];
        }
        $cacheData = serialize($menu_cache);
        $this->cacheWrite($cacheData, 'menus');
    }
    // 敏感词缓存
    private function mc_sensitives() {
        $sensitive_cache = array();
        $res = $this->db->query("SELECT * FROM `" . DB_PREFIX . "sys_sensitive` WHERE isdel='0'");
        while ($row = $this->db->fetch_array($res)) {
            $sensitive_cache[] = array(
                'id' =>$row['id'],
                'flid' =>$row['flid'],
                'sname' =>$row['sname'],
                'replace' =>$row['replace'],
                'istype' => $row['istype'],
                'create_time' => $row['create_time'],
                );
        }
        $cacheData = serialize($sensitive_cache);
        $this->cacheWrite($cacheData, 'sensitives');
    }
    /**
     * 写入缓存
     */
    function cacheWrite ($cacheData, $cacheName) {
        $cachefile = PASH_ROOT . '/runtime/cache/' . $cacheName . '.php';
        $cacheData = "<?php exit;//" . $cacheData;
        @ $fp = fopen($cachefile, 'wb') OR kmMsg('读取缓存失败。如果您使用的是Unix/Linux主机，请修改缓存目录 (content/cache) 下所有文件的权限为777。如果您使用的是Windows主机，请联系管理员，将该目录下所有文件设为可写'. $cachefile);
        @ $fw = fwrite($fp, $cacheData) OR kmMsg('写入缓存失败，缓存目录 (content/cache) 不可写');
        $this->{$cacheName.'_cache'} = null;
        fclose($fp);
    }
    /**
     * 读取缓存文件
     */
    function readCache($cacheName) {
        if ($this->{$cacheName.'_cache'} != null) {
            return $this->{$cacheName.'_cache'};
        } else {
            $cachefile = PASH_ROOT . '/runtime/cache/' . $cacheName . '.php';
            // 如果缓存文件不存在则自动生成缓存文件
            if (!is_file($cachefile) || filesize($cachefile) <= 0) {
                if (method_exists($this, 'mc_' . $cacheName)) {
                    call_user_func(array($this, 'mc_' . $cacheName));
                }
            }
            if ($fp = fopen($cachefile, 'r')) {
                $data = fread($fp, filesize($cachefile));
                fclose($fp);
                clearstatcache();
                $this->{$cacheName.'_cache'} = unserialize(str_replace("<?php exit;//", '', $data));
                return $this->{$cacheName.'_cache'};
            }
        }
    }
}
